#pragma once
#include "../db_common.h"
#include "../complier/lexer.hpp"
#include "../complier/parser.hpp"
#include "../complier/plan_builder.hpp"
#include "../complier/error.h"
#include "../DB-OS/storage_engine.h"
#include "page/db_page.h"
class SQLCompiler
{
public:
    static CompileResult compile(const std::string &sql,
                                 const std::unordered_map<std::string, TableSchema> &schema)
    {
        CompileResult res;

        try
        {
            // 1. 词法分析
            Lexer lexer(sql);
            lexer.lexAll();

            // 2. 语法分析
            Parser parser{lexer.out};
            auto stmt = parser.parseOne();

            // 3. 生成执行计划
            PlanBuilder builder(schema);
            res = builder.build(stmt);
        }
        catch (const LexicalException &e)
        {
            res.status = "error";
            res.error.error_type = "Lexical Error";
            res.error.message = e.what();
            res.error.line = e.line;
            res.error.column = e.column;
        }
        catch (const SyntaxException &e)
        {
            res.status = "error";
            res.error.error_type = "Syntax Error";
            res.error.message = e.what();
            res.error.line = e.line;
            res.error.column = e.column;
        }
        catch (const SemanticException &e)
        {
            res.status = "error";
            res.error.error_type = "Semantic Error";
            res.error.message = e.what();
            res.error.line = e.line;
            res.error.column = e.column;
        }

        return res;
    }
};

class StorageSystem
{
private:
    static StorageEngine &getEngine();
    static page_id_t current_page_id;
    static std::unordered_map<page_id_t, std::vector<uint8_t>> pages;

public:
    static StorageResult allocate_page()
    {
        page_id_t page_id = getEngine().allocate_page();
        StorageResult res;
        res.status = "success";
        res.page_id = page_id;
        return res;
        // pages[current_page_id] = std::vector<uint8_t>(REAL_PAGE_SIZE, 0);
        // StorageResult res;
        // res.status = "success";
        // res.page_id = current_page_id;
        // res.page_data = pages[current_page_id];
        // current_page_id++;
        // return res;
    }

    static StorageResult get_page(page_id_t page_id)
    {
        StorageResult res;
        res.status = "success";
        res.page_id = page_id;
        auto page = getEngine().read_page(page_id);
        const uint8_t *start = reinterpret_cast<const uint8_t *>(page->get_data());
        const uint8_t *end = start + page->get_data_size();
        res.page_data = std::vector<uint8_t>(start, end);
        return res;
        // StorageResult res;
        // res.status = "success";
        // res.page_id = page_id;
        // res.page_data = pages[page_id];
        // return res;
    }

    static StorageResult write_page(page_id_t page_id, const std::vector<uint8_t> &data)
    {
        StorageResult res;
        res.status = "success";
        const char *data_ = reinterpret_cast<const char *>(data.data());
        auto origin_page = getEngine().read_page(page_id);
        char *dest_data = origin_page->get_data();

        // 使用 memcpy 来复制指定大小的内存块
        // data.data() 是源地址
        // data.size() 是要复制的字节数
        memcpy(dest_data, data.data(), data.size());
        getEngine().write_page(origin_page);
        return res;
        // StorageResult res;
        // res.status = "success";
        // pages[page_id] = data;
        // return res;
    }

    static bool free_page(page_id_t page_id)
    {
        return getEngine().free_page(page_id);
        // pages.erase(page_id);
        // return true;
    }

    static bool free_pages(const std::vector<uint32_t> &page_ids)
    {
        bool all_success = true;
        for (auto page_id : page_ids)
        {
            if (!free_page(page_id))
            {
                all_success = false; // 单个删除失败，标记整体失败
            }
        }
        return all_success; // 必须返回bool值
    }
};
